package com.neutech.maplestory.entity;

import com.neutech.maplestory.client.MapleStoryClient;
import com.neutech.maplestory.constant.Constant;
import com.neutech.maplestory.util.ImageUtil;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.List;
import java.util.Random;

/**
 * 英雄类
 */
public class Hero extends AbstractMapleStoryObject {
    /**
     * 数组图片，存放人物的
     */
    public static Image[] images = new Image[100];
    /**
     * 开关，按键的设置的开关
     */
    private boolean left;//向左
    private boolean right;//向右
    private boolean down;//向下趴着
    private boolean jump;//跳起来
    private boolean shoot;//攻击发射
    private boolean pickUp;//捡起道具
    public boolean fly;//飞的状态
    private boolean fly_left;
    private boolean fly_right;
    private boolean fly_up;
    private boolean fly_down;

    /**
     * 最开始初始化加载图片，加载从util拿过来的图片
     */
    static {
        /**
         * 人物右面站着
         */
        for (int i = 0; i < 4; i++) {
            images[i] = ImageUtil.getImage("hero_right_stand" + i);
        }
        /**
         * 人物左面站着
         */
        for (int i = 4; i < 8; i++) {
            images[i] = ImageUtil.getImage("hero_left_stand" + (i - 4));
        }
        /**
         * 人物右面走
         */
        for (int i = 8; i < 13; i++) {
            images[i] = ImageUtil.getImage("hero_right_walk" + (i - 8));
        }
        /**
         * 人物左面走
         */
        for (int i = 13; i < 18; i++) {
            images[i] = ImageUtil.getImage("hero_left_walk" + (i - 13));
        }
        /**
         * 人物右面趴着左面趴着，右面跳，左面跳
         */
        images[18] = ImageUtil.getImage("hero_right_prone");
        images[19] = ImageUtil.getImage("hero_left_prone");
        images[20] = ImageUtil.getImage("hero_right_jump");
        images[21] = ImageUtil.getImage("hero_left_jump");
        /**
         * 人物右面射击
         */
        for (int i = 22; i < 26; i++) {
            images[i] = ImageUtil.getImage("hero_right_shoot" + (i - 22));
        }
        /**
         * 人物右面射击
         */
        for (int i = 26; i < 30; i++) {
            images[i] = ImageUtil.getImage("hero_left_shoot" + (i - 26));
        }
        /**
         * 人物右面飞
         */
        for (int i = 30; i < 33; i++) {
            images[i] = ImageUtil.getImage("hero_right_fly" + (i - 30));
        }
        /**
         * 人物左面飞
         */
        for (int i = 33; i < 36; i++) {
            images[i] = ImageUtil.getImage("hero_left_fly" + (i - 33));
        }
        for (int i = 36; i < 38; i++) {
            images[i] = ImageUtil.getImage("climb" + (i - 36));
        }
    }


    public int Mp;//魔法值
    public int HP;//生命值
    public int MAX_HP = 1000;//最大生命值
    public int MAX_MP = 1000;//最大魔法值
    public int attack;//初始攻击力
    public int hitValue;//攻击值
    public boolean climb;
    public boolean up;
    public boolean downRope;
    public Random random = new Random();

    /**
     * 英雄类，初始化英雄的属性
     *
     * @param x 英雄出现的x坐标
     * @param y 英雄出现的y坐标
     */
    public Hero(MapleStoryClient msc, int x, int y) {
        this.msc = msc;
        this.x = x;
        this.y = y;
        this.attack = 2345;
        this.speed = Constant.SPEED;
        this.width = images[0].getWidth(null);
        this.height = images[0].getHeight(null);
        this.dir = Direction.RIGHT;
        this.action = Action.STAND;
        this.Mp = MAX_MP;
        this.HP = MAX_HP;
    }

    private int count = 0;
    private int step = 0;


    /**
     * 画英雄的方法
     *
     * @param g 画笔
     */
    @Override
    public void draw(Graphics g) {
        /**
         * 画出英雄的血条和蓝条
         */
        Color color = g.getColor();
        g.drawRect(this.x, this.y - 30, this.width, 10);
        g.drawRect(this.x, this.y - 18, this.width, 10);
        g.setColor(Color.green);
        g.fillRect(this.x + 1, this.y - 29, (int) (this.width * this.HP / MAX_HP), 10 - 1);
        g.setColor(Color.CYAN);
        g.fillRect(this.x + 1, this.y - 17, (int) (this.width * this.Mp / MAX_MP), 10 - 1);
        g.setColor(color);
        /**
         * 第一层判断方向的
         */
        switch (this.dir) {
            /**
             * 向右方向
             */
            case RIGHT://右方向
                /**
                 * 嵌套switch来判断状态，看他是跑还是站着的
                 */
                switch (this.action) {
                    case STAND://右面站着的人物
                        if (count++ % 5 == 0) {
                            /**
                             * 类似于以下取余是有几张图片就对几取余，加几是前面有多少张图片就加几
                             */
                            g.drawImage(images[step++ % 4], x, y, null);
                        } else {
                            g.drawImage(images[step % 4], x, y, null);
                        }
                        break;
                    case WALK://右面跑着的人物
                        if (count++ % 5 == 0) {
                            g.drawImage(images[(step++ % 5) + 8], x, y, null);
                        } else {
                            g.drawImage(images[step % 5 + 8], x, y, null);
                        }
                        break;
                    case PRONE://右面趴着的
                        g.drawImage(images[18], x + 30, y + 32, null);
                        break;
                    case JUMP://右面跳
                        g.drawImage(images[20], x, y, null);
                        break;
                    case SHOOT://右面射击的人物
                        if (count++ % 5 == 0) {
                            g.drawImage(images[(step++ % 4) + 22], x, y, null);
                        } else {
                            g.drawImage(images[step % 4 + 22], x, y, null);
                        }
                        break;
                    case CLIMB:
                        if (count++ % 5 == 0) {
                            g.drawImage(images[step++ % 2 + 36], x, y, null);
                        } else {
                            g.drawImage(images[step % 2 + 36], x, y, null);
                        }
                        break;

                    case FLY:
                        if (count++ % 5 == 0) {
                            g.drawImage(images[(step++ % 3) + 30], x, y, null);
                        } else {
                            g.drawImage(images[(step % 3) + 30], x, y, null);
                        }
                        break;
                }

                move();
                break;
            case LEFT://左方向
                switch (this.action) {
                    case STAND://左面站着的人物  取余表示几张图片就对几区域
                        if (count++ % 5 == 0) {
                            g.drawImage(images[(step++ % 4) + 4], x, y, null);
                        } else {
                            g.drawImage(images[step % 4 + 4], x, y, null);
                        }
                        break;
                    case WALK://左面跑的人物
                        if (count++ % 5 == 0) {
                            g.drawImage(images[(step++ % 5) + 13], x, y, null);
                        } else {
                            g.drawImage(images[step % 5 + 13], x, y, null);
                        }
                        break;
                    case PRONE://左面趴着的
                        g.drawImage(images[19], x - 30, y + 32, null);
                        break;
                    case JUMP://左面跳
                        g.drawImage(images[21], x, y, null);
                        break;
                    case CLIMB:
                        if (count++ % 5 == 0) {
                            g.drawImage(images[step++ % 2 + 36], x, y, null);
                        } else {
                            g.drawImage(images[step % 2 + 36], x, y, null);
                        }
                        break;
                    case SHOOT://左面射击的人物
                        if (count++ % 5 == 0) {
                            g.drawImage(images[(step++ % 4) + 26], x, y, null);
                        } else {
                            g.drawImage(images[step % 4 + 26], x, y, null);
                        }
                        break;
                    case FLY:
                        if (count++ % 5 == 0) {
                            g.drawImage(images[(step++ % 3) + 33], x, y, null);
                        } else {
                            g.drawImage(images[(step % 3) + 33], x, y, null);
                        }
                        break;
                }
                move();
                break;
        }

    }

    /**
     * 移动的方法，通过开关来实现
     */
    @Override
    public void move() {
        if (right && !left) {//如果向右不向左
            this.x += speed;//向右走
            if (jump) {//如果跳就调用跳的方法
                jump(msc.grounds);

            } else if (!fly && !up && !downRope) {
                jumpDown(msc.grounds);
            }
            if (shoot) {//如果射击就调用射击的方法
                shoot();
            }
        } else if (left && !right) {
            this.x -= speed;
            if (jump && !up) {
                jump(msc.grounds);
            } else if (!fly && !up && !downRope) {
                jumpDown(msc.grounds);
            }
            if (shoot) {
                shoot();
            }
        }
        if (jump && !up) {
            jump(msc.grounds);
            if (shoot) {
                shoot();
            }
        } else if (!fly && !up && !downRope) {
            jumpDown(msc.grounds);
        }
        if (shoot) {
            shoot();
        } else if (pickUp) {
            pickUp(msc.itemList);
        }
        confirmStatus();
        if (!fly) {
            outOfBund();
        }
        climb();

    }

    /**
     * 射击的方法
     */
    private int shootCount = 0;

    private void shoot() {
        shootCount++;
        if (shootCount % 10 == 0) {
//            shoot = false;
            this.Mp -= 10;
            Arrow arrow;
            if (this.dir == Direction.RIGHT) {
                arrow = new Arrow(msc, x + this.width, y + this.height / 2 + 10, dir);
            } else {
                arrow = new Arrow(msc, x, y + this.height / 2 + 10, dir);
            }
            msc.arrowList.add(arrow);
            shoot = false;
        }
    }

    private double v0 = Constant.INIT_JUMP_SPEED;
    private double vt;
    private double g = 9.8;
    private double delta_height;
    private double t = 0.7;


    private boolean drop = true;

    public void jump(List<Ground> grounds) {
        if (!drop) {
            vt = v0 - g * t;
            delta_height = v0 * t;
            v0 = vt;
            y -= delta_height;
            if (vt <= 0) {
                vt = 0.0;
                drop = true;
            }
        } else {
            jumpDown(grounds);
        }
    }
    public void climb(){

        if (up && !downRope) {

            this.y -= speed;

        }
        if (downRope && !up) {

            this.y += speed;

        }
    }

    public void jumpDown(List<Ground> grounds) {
        vt = v0 + g * t;
        delta_height = v0 * t;
        v0 = vt;
        y += delta_height;
        for (int i = 0; i < grounds.size(); i++) {
            Ground ground = grounds.get(i);
            if (this.getRectangle().intersects(ground.getRectangle()) && this.y <= ground.y - this.height + 80) {
                if (this.y >= (ground.y - this.height)) {
                    this.y = ground.y - this.height;
                    drop = false;
                    jump = false;
                    v0 = Constant.INIT_JUMP_SPEED;
                    vt = 0.0;
                    break;
                }
            } else {
                drop = true;
            }
        }
    }

//    private boolean jump1 = true;
//    /**
//     * 跳跃的方法
//     */
//    private void jump(List<Ground> grounds){
//        //向上跳
//        vt = v0 - g * t;
//        delta_height = v0 * t;
//        v0 = vt;
//        y -= delta_height;
//        if (vt <= 0){
//            vt = 0;
//            jump1 = false;
//            jumpDown(msc.grounds);
//        }
//    }
//    /**
//     * 掉落的方法
//     */
//    public void jumpDown(List<Ground> grounds){
//        jump = false;
//        //掉的过程，自由落体
//        vt = v0 + g * t;
//        delta_height = v0 * t;
//        v0 = vt;
//        y += delta_height;
//        //什么时候停止自由落体
//        for (int i = 0; i < grounds.size(); i++) {
//            Ground ground = grounds.get(i);
//            if (this.getRectangle().intersects(ground.getRectangle()) /*&& this.y <= ground.y - this.height + 40*/){
//                if (this.y >= ground.y - this.height){
//                    this.y = ground.y - this.height;
//                    v0 = Constant.INIT_JUMP_SPEED;
//                    vt = 0.0;
//                    break;
//                }
//            }
//        }
//    }

//    private void jump() {
//        vt = v0 - g * t;
//        v0 = vt;
//        delta_height = v0 * t;
//        y -= delta_height;
//        if (y >= 510) {
//            jump = false;
//            v0 = Constant.INIT_JUMP_SPEED;
//            vt = 0.0;
//            y = 510;
//        }
//    }

    private int flyCount = 0;

    /**
     * 根据当前开关来判断方向
     */
    public void confirmStatus() {
        if (this.Mp <= 0) {
            this.fly = false;
        }
        if (left && !right) {
            this.dir = Direction.LEFT;
            this.action = Action.WALK;
            if (jump) {
                this.action = Action.JUMP;
            }

        } else if (right && !left) {
            this.dir = Direction.RIGHT;
            this.action = Action.WALK;
            if (jump) {
                this.action = Action.JUMP;
            }
        } else if (down) {
            this.action = Action.PRONE;
        } else if (jump) {
            this.action = Action.JUMP;
        } else if (shoot) {
            this.action = Action.SHOOT;
        }
        if (fly) {
            this.action = Action.FLY;
            flyCount++;
            if (flyCount % 30 == 0) {
                this.Mp -= 30; // todo 魔法值
            }
            if (fly_left) {
                this.x -= speed;
            } else if (fly_up) {
                this.y -= speed;
            } else if (fly_right) {
                this.x += speed;
            } else if (fly_down) {
                this.y += speed;
            }
            if (shoot) {
                this.action = Action.SHOOT;
            }
        } else {
            this.action = Action.STAND;
        }
        if (fly == false) {
//            this.y += speed;
//            this.right = false;
//            this.left = false;
//            this.action = Action.STAND;
            if (!jump && !up && !downRope) {
                jumpDown(msc.grounds);
            }
            if (!right && !left) {
                this.action = Action.STAND;
            }
            if (jump) {
                this.action = Action.JUMP;
            }
            if (right || left) {
                this.action = Action.WALK;
            }
            if (shoot) {
                this.action = Action.SHOOT;
            }
            if (up ) {
                this.action = Action.CLIMB;
                if (left || right){
                    up =false;
                }
            }if (downRope ){
                this.action = Action.CLIMB;
                if (left || right){
                    downRope =false;
                }
            }
        }

    }

    /**
     * 走路按下按键的方法
     *
     * @param e 按键
     */
    public void keyPressed(KeyEvent e) {
        switch (e.getKeyCode()) {
            case KeyEvent.VK_A:
                if (!fly) {
                    left = true;
                }
                break;
            case KeyEvent.VK_D:
                if (!fly) {
                    right = true;
                }

                break;
            case KeyEvent.VK_S:
                if (!fly) {
                    downRope = true;
                    up = false;
                }
                break;
            case KeyEvent.VK_W:
                if (!fly) {
                        up = true;
                        downRope = false;


                }
                break;
            case KeyEvent.VK_K:
                if (!fly) {
                    jump = true;
                }
                break;
            case KeyEvent.VK_J:
                if (this.Mp > 0) {
                    shoot = true;
                }

                break;
            case KeyEvent.VK_E:
                pickUp = true;
                break;
            case KeyEvent.VK_L:
                if (this.Mp > 0) {
                    fly = !fly;
                }

            default:
                break;
        }
    }

    public void keypress(KeyEvent e) {
        switch (e.getKeyCode()) {
            case KeyEvent.VK_W:
                this.fly_up = true;
                if (this.y <= 0) {
//                    this.y = 0;
                    this.fly_up = false;
                }
                break;
            case KeyEvent.VK_D:
                this.dir = Direction.RIGHT;
                this.fly_right = true;
                if (this.x >= Constant.GAME_WINDOW_WIDTH - this.width) {
//                    this.x = Constant.GAME_WINDOW_WIDTH - this.width;
                    this.fly_right = false;
                }
                break;

            case KeyEvent.VK_S:
                this.fly_down = true;
                if (this.y >= Constant.GAME_WINDOW_HEIGHT - this.width) {
//                    this.y = Constant.GAME_WINDOW_HEIGHT - this.width;
                    this.fly_down = false;
                }
                break;
            case KeyEvent.VK_A:
                this.dir = Direction.LEFT;
                this.fly_left = true;
                if (this.x <= 0) {
//                    this.x = 0;
                    this.fly_left = false;
                }
                break;
            default:
                break;
        }
    }

    public void keyRelease(KeyEvent e) {
        switch (e.getKeyCode()) {
            case KeyEvent.VK_W:
                this.fly_up = false;
                break;
            case KeyEvent.VK_D:
                this.fly_right = false;
                break;
            case KeyEvent.VK_S:
                this.fly_down = false;
                break;
            case KeyEvent.VK_A:
                this.fly_left = false;
                break;
        }
    }


    /**
     * 释放按键的方法
     *
     * @param e 画笔
     */
    public void keyReleased(KeyEvent e) {
        switch (e.getKeyCode()) {
            case KeyEvent.VK_A:
                left = false;
                break;

            case KeyEvent.VK_D:
                right = false;
                break;
            case KeyEvent.VK_S:
                down = false;
                break;
            case KeyEvent.VK_E:
                pickUp = false;
                break;
            case KeyEvent.VK_W:
                if (climb && !fly) {
                    up = false;
                }
                break;
            default:
                break;
        }

    }

    /**
     * 人物出界
     */
    private void outOfBund() {
        if (this.x <= 0) {
            this.x = 0;
        } else if (this.x >= Constant.GAME_WINDOW_WIDTH - this.width) {
            this.x = Constant.GAME_WINDOW_WIDTH - this.width;
        } else if (this.dir == Direction.RIGHT) {
            if (this.x >= 605 - this.width && this.y >= 540 - this.height + 40 && this.x <= 775 && this.y <= 780) {
                this.x = 605 - this.width;
            }
            if (this.x >= 1080 - this.width && this.y >= 540 - this.height + 40 && this.x <= 1250 - this.width && this.y <= 780) {
                this.x = 1080 - this.width;
            }
            if (this.x >= 1585 - this.width && this.y >= 440 - this.height + 40 && this.x <= 1675 - this.width && this.y <= 780) {
                this.x = 1585 - this.width;
            }
            if (this.x >= 1360 - this.width + 40 && this.x <= 1585 + 40 && this.y >= 170 - this.height && this.y <= 610) {
                this.y = this.y - (this.x - 1360);
                if (this.y <= 440 - this.height) {
                    this.y = 440 - this.height;
                }
            }
        } else if (this.dir == Direction.LEFT) {
            if (this.x <= 775 && y >= 540 && this.x >= 605 && this.y <= 780) {
                this.x = 775;
            }
            if (this.x <= 1255 && this.x >= 1080 && this.y >= 540 - this.height + 40 && this.y <= 780) {
                this.x = 1250;
            }
            if (this.x <= 1675 && this.x >= 1585 && this.y >= 440 - this.height + 40 && this.y <= 780) {
                this.x = 1675;
            }
            if (this.y <= 780 && this.y >= 770) {
                jumpDown(msc.grounds);
            }
        }
        if (this.x>=420 && this.x <= 430 && this.y <= 508 && this.y>=268 ){
            this.action = Action.CLIMB;
        }else {
            up = false;
        }


    }

    private boolean pickUp(Item item) {
        if (item.live && this.getRectangle().intersects(item.getRectangle())) {
            item.live = false;
            //判断存放之前和包里每一个道具进行比较
            for (int i = 0; i < msc.itemPackage.packItemList.size(); i++) {
                Item item1 = msc.itemPackage.packItemList.get(i);
                //如果相同则加一
                if (item1.type == item.type) {
                    item1.quantity += 1;
                    return false;
                }
            }
            msc.itemPackage.packItemList.add(item);
        }
        return false;
    }

    /**
     * 按下按键吃药
     *
     * @param k    按键
     * @param item 背包里面的药品
     */
    private int quantityCount = 0;

    public void keyPress(KeyEvent k, Item item) {
        quantityCount++;
        if (k.getKeyCode() == KeyEvent.VK_1) {
            for (int i = 0; i < msc.itemPackage.packItemList.size(); i++) {
                item = msc.itemPackage.packItemList.get(i);
                if (item.type == 0) {
                    if (quantityCount % 2 == 0) {
                        item.quantity -= 1;
                    }
                    if (item.quantity <= 0) {
                        msc.itemPackage.packItemList.remove(item);
                    }
                    this.HP += 100;
                    if (this.HP >= this.MAX_HP) {
                        this.HP = this.MAX_HP;
                    }
                }
            }
        } else if (k.getKeyCode() == KeyEvent.VK_2) {
            for (int i = 0; i < msc.itemPackage.packItemList.size(); i++) {
                item = msc.itemPackage.packItemList.get(i);
                if (item.type == 1) {
                    if (quantityCount % 2 == 0) {
                        item.quantity -= 1;
                    }
                    if (item.quantity <= 0) {
                        msc.itemPackage.packItemList.remove(item);
                    }
                    this.HP += 300;
                    if (this.HP >= this.MAX_HP) {
                        this.HP = this.MAX_HP;
                    }
                }
            }
        } else if (k.getKeyCode() == KeyEvent.VK_3) {
            for (int i = 0; i < msc.itemPackage.packItemList.size(); i++) {
                item = msc.itemPackage.packItemList.get(i);
                if (item.type == 2) {
                    if (quantityCount % 2 == 0) {
                        item.quantity -= 1;
                    }
                    if (item.quantity <= 0) {
                        msc.itemPackage.packItemList.remove(item);
                    }
                    this.Mp += 100;
                    if (this.Mp >= this.MAX_MP) {
                        this.Mp = this.MAX_MP;
                    }
                }
            }
        } else if (k.getKeyCode() == KeyEvent.VK_4) {
            for (int i = 0; i < msc.itemPackage.packItemList.size(); i++) {
                item = msc.itemPackage.packItemList.get(i);
                if (item.type == 3) {
                    if (quantityCount % 2 == 0) {
                        item.quantity -= 1;
                    }
                    if (item.quantity <= 0) {
                        msc.itemPackage.packItemList.remove(item);
                    }
                    this.Mp += 300;
                    if (this.Mp >= this.MAX_MP) {
                        this.Mp = this.MAX_MP;
                    }
                }
            }
        } else if (k.getKeyCode() == KeyEvent.VK_5) {
            for (int i = 0; i < msc.itemPackage.packItemList.size(); i++) {
                item = msc.itemPackage.packItemList.get(i);
                if (item.type == 4) {
                    if (quantityCount % 2 == 0) {
                        item.quantity -= 1;
                    }
                    if (item.quantity <= 0) {
                        msc.itemPackage.packItemList.remove(item);
                    }
                    int attackTime = 0;
                    attackTime++;
                    if (attackTime < 1000) {
                        this.attack += 300;
                    }
                }
            }
        } else if (k.getKeyCode() == KeyEvent.VK_6) {
            for (int i = 0; i < msc.itemPackage.packItemList.size(); i++) {
                item = msc.itemPackage.packItemList.get(i);
                if (item.type == 5) {
                    if (quantityCount % 2 == 0) {
                        item.quantity -= 1;
                    }
                    if (item.quantity <= 0) {
                        msc.itemPackage.packItemList.remove(item);
                    }
                    int attackTime = 0;
                    attackTime++;
                    if (attackTime < 3000) {
                        this.attack += 510;
                    }
                }
            }

        }
    }

    /**
     * 捡道具的方法
     *
     * @param itemList 道具们
     * @return 返回是否
     */
    public boolean pickUp(List<Item> itemList) {
        for (int i = 0; i < itemList.size(); i++) {
            Item item = itemList.get(i);
            if (pickUp(item)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 英雄碰怪物
     *
     * @param mob 某个怪物
     * @return 返回是否
     */
    int hitTime = 0;

    private boolean hit(Mob mob) {

        if (this.getRectangle().intersects(mob.getRectangle())) {
            hitTime++;
            if (hitTime % 10 == 0) {
                this.HP -= 10; // todo 生命值的修改
            }
            if (this.HP <= 0) {
                this.live = false;
            }

        }
        return false;
    }

    /**
     * 英雄碰一群怪物
     *
     * @param mobs 一群怪物
     * @return 返回是否
     */
    public boolean hit(List<Mob> mobs) {
        //遍历怪物集合
        for (int i = 0; i < mobs.size(); i++) {
            //拿到每一个怪物
            Mob mob = mobs.get(i);
            //把拿到的每一个怪物传到上面的打击的方法里面
            if (hit(mob)) {
                return true;
            }
        }
        return false;
    }


}
